﻿using System.Linq;
using RpcClient;
using RpcHelper;
using RpcModel;
using Wedonek.RpcStore.Gateway.Interface;
using Wedonek.RpcStore.Gateway.Model;
using Wedonek.RpcStore.Service.Interface;
using Wedonek.RpcStore.Service.Model;

namespace Wedonek.RpcStore.Gateway.Service
{
    internal class ServerTransmitService : IServerTransmitService
    {
        private readonly IServerTransmitCollect _Transmit;
        private readonly IServerTypeCollect _ServerType;
        private readonly IServerCollect _Server;
        public ServerTransmitService(IServerTransmitCollect transmit,
            IServerTypeCollect serverType,
            IServerCollect server)
        {
            this._ServerType = serverType;
            this._Server = server;
            this._Transmit = transmit;
        }
        /// <summary>
        /// 添加节点类型负载方案
        /// </summary>
        /// <param name="add"></param>
        /// <returns></returns>
        public long Add(TransmitSchemeAdd add)
        {
            this._Transmit.CheckRepeat(add.RpcMerId, add.SystemType, add.Scheme);
            ServerTransmitConfig config = add.ConvertMap<TransmitSchemeAdd, ServerTransmitConfig>();
            return this._Transmit.Add(config);
        }
        /// <summary>
        /// 添加服务节点方案
        /// </summary>
        /// <param name="add"></param>
        /// <returns></returns>
        public long Add(TransmitBasicAdd add)
        {
            ServerConfigDatum datum = this._Server.Get(add.SeverId);
            this._Transmit.CheckRepeat(add.RpcMerId, add.Scheme, add.SeverId);
            ServerTransmitConfig config = add.ConvertMap<TransmitBasicAdd, ServerTransmitConfig>();
            config.SystemTypeId = datum.SystemType;
            config.TransmitConfig.ForEach(a =>
            {
                if (!a.Range.IsNull() && a.Range.Length > 1)
                {
                    a.Range = a.Range.OrderBy(a => a.BeginRange).ToArray();
                }
            });
            return this._Transmit.Add(config);
        }

        public void Delete(long id)
        {
            ServerTransmitConfig config = this._Transmit.Get(id);
            if (config.IsEnable)
            {
                throw new ErrorException("rpc.store.transmit.already.enable");
            }
            this._Transmit.Delete(config);
        }

        public ServerTransmitConfig Get(long id)
        {
            return this._Transmit.Get(id);
        }

        public ServerTransmitDatum[] Query(TransmitQueryParam query, IBasicPage paging, out long count)
        {
            TransmitBasicConfig[] list = this._Transmit.Query(query, paging, out count);
            if (list.Length == 0)
            {
                return System.Array.Empty<ServerTransmitDatum>();
            }
            BasicService[] services = this._Server.GetBasic(list.Convert(a => a.SeverId != 0, a => a.SeverId));
            BasicServerType[] types = this._ServerType.GetBasic(list.ConvertAll(a => a.SystemTypeId));
            return list.ConvertMap<TransmitBasicConfig, ServerTransmitDatum>((a, b) =>
            {
                if (a.SeverId != 0)
                {
                    b.Sever = services.Find(c => c.Id == a.SeverId, c => c.ServerName);
                }
                b.SystemType = types.Find(c => c.Id == a.SystemTypeId, c => c.SystemName);
                return b;
            });
        }

        public void Set(long id, TransmitSetParam set)
        {
            ServerTransmitConfig config = this._Transmit.Get(id);
            if (config.IsEnable)
            {
                throw new ErrorException("rpc.store.transmit.already.enable");
            }
            this._Transmit.Set(config, set);
        }

        public void SetIsEnable(long id, bool isEnable)
        {
            ServerTransmitConfig config = this._Transmit.Get(id);
            if (config.IsEnable)
            {
                throw new ErrorException("rpc.store.transmit.already.enable");
            }
            this._Transmit.SetIsEnable(config, isEnable);
        }
    }
}
